#include <iostream>
#include <cstring>
#include <fstream>
#include <sstream>

#include <cv.h>
#include <cvaux.h>
#include <highgui.h>

using namespace std;
using namespace cv;

static void read_csv(const string& filename, vector<Mat>& images, vector<float>& labels, char separator = ';') {
    std::ifstream file(filename.c_str(), ifstream::in);
    if (!file) {
        string error_message = "No valid input file was given, please check the given filename.";
        CV_Error(CV_StsBadArg, error_message);
    }
    string line, path, classlabel;
    while (getline(file, line)) {
        stringstream liness(line);
        getline(liness, path, separator);
        getline(liness, classlabel);
        if(!path.empty() && !classlabel.empty()) {
            images.push_back(imread(path,CV_LOAD_IMAGE_COLOR));
            labels.push_back(atof(classlabel.c_str()));
	    //printf("PUSH:%d\n",atoi(classlabel.c_str()));
        }
    }
}

int main(int argc, char **argv)
{
  vector<Mat> images;
  vector<float> labels;
  read_csv(string(argv[1]),images,labels);
  cout << labels[0] << " ";
  int fCount=1;
  double entropies[7];
  double aveSats[7];
  for(int i=0;i<images.size()/2;i++)
  {
    Mat sat;
    vector<Mat> mv;
    split(images[i],mv);
    Mat hist;
    /// Compute the histograms:    
    int histSize = 256;
    /// Set the ranges ( for B,G,R) )
    float range[] = { 0, 256 } ;
    const float* histRange = { range };
    bool uniform = true; bool accumulate = false;
    calcHist( &mv[0], 1, 0, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate );
    entropies[i]=0;
    for(int j=0;j<hist.rows;j++)
    {
	double r=hist.at<float>(j)/(mv[0].cols*mv[0].rows);
	if(r!=0)
	    entropies[i]-=r*log2(r);
    }

    cvtColor(images[i],sat, CV_BGR2HLS);
    aveSats[i]=0;
    for(int x=0;x<sat.rows;x++)
    {
	for (int y=0;y<sat.cols;y++)
	{
	    aveSats[i]+=sat.at<Vec3b>(x,y)[2];
	    //printf("%lf ",sat.at<Vec3b>(x,y)[1]);
	}
    }
    aveSats[i]=aveSats[i]/(sat.cols*sat.rows);
  }
  for(int i=0;i<7;i++)
    printf("%d:%lf ",fCount++,entropies[i]);
  for(int i=0;i<7;i++)
    printf("%d:%lf ",fCount++,aveSats[i]/25.50);
  
  
  double stdevs[7],frecks[7];
  for(int i=7;i<14;i++)
  {
    Scalar stdev,mean;
    Mat dest(images[i].rows,images[i].cols,CV_8UC1);
    //GaussianBlur(images[i],images[i],Size(3,3),0,0);
    cvtColor(images[i],dest,CV_BGR2GRAY);
    //imshow("123",images[i]);
    //waitKey(0);
    //threshold(images[i],images[i],175,255,THRESH_TRUNC);
    meanStdDev(dest,mean,stdev);    
    //printf("%d:%lf ",fCount++,mean.val[0]/255);
    //printf("%d:%lf ",fCount++,stdev.val[0]);
    stdevs[i-7]=stdev.val[0];
    //printf("%d:%lf ",fCount++,mean.val[0]/255);
    threshold( dest, dest, mean.val[0]-2*stdev.val[0], 255 , 1 );
    meanStdDev(dest,mean,stdev); 
    //printf("%d:%lf ",fCount++,mean.val[0]);
    frecks[i-7]=mean.val[0];
  }
   
  
  for(int i=0;i<7;i++)
    printf("%d:%lf ",fCount++,stdevs[i]);
  for(int i=0;i<7;i++)
    printf("%d:%lf ",fCount++,frecks[i]);
  
  double aveH[7],aveL[7],aveS[7];
  int R[7],C[7];
  for(int i=14;i<21;i++)
  {
    Scalar stdev,mean;
    vector<Mat> mv;
    Mat dest;
    cvtColor(images[i],dest,CV_BGR2HLS);
    split(dest,mv);
    meanStdDev(mv[0],mean,stdev);
    aveH[i-14]=mean.val[0];
    meanStdDev(mv[1],mean,stdev);
    aveL[i-14]=mean.val[0];
    meanStdDev(mv[2],mean,stdev);
    aveS[i-14]=mean.val[0];
    R[i-14]=dest.rows;
    C[i-14]=dest.cols;
    
  }
  double tH=0,tL=0,tS=0;
  double tP=0;
  for(int i=0;i<7;i++)
  {
      tH+=aveH[i]*R[i]*C[i];
      tL+=aveL[i]*R[i]*C[i];
      tS+=aveS[i]*R[i]*C[i];
      tP+=R[i]*C[i];
  }
  printf("%d:%lf ",fCount++,tH/tP/25.5);
  printf("%d:%lf ",fCount++,tL/tP/25.5);
  printf("%d:%lf ",fCount++,tS/tP/25.5);
  
  
  cout << endl;
}
